package com.ws.shop.util;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

public class DateUtil {
	private static Logger log = Logger.getLogger(DateUtil.class);
	public static final String YYYY_MM_DD = "yyyy-MM-dd";
	public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
	public static final String YYYYMMDD = "yyyyMMdd";
	public static final String YYMMDD = "yyMMdd";
	public static final String YYMMDDHHMMSS = "yyMMddHHmmss";
	public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
	public static final String YYMMDDHHMMSSSSS = "yyMMddHHmmssSSS";
	private static ThreadLocal<Map<String, DateFormat>> threadLocal = new ThreadLocal<Map<String, DateFormat>>() {
		protected Map<String, DateFormat> initialValue() {
			return new HashMap<String, DateFormat>();
		}
	};

	/**
	 * 计算日期相隔多少天
	 * 
	 * @param sdate
	 * @param edate
	 * @return
	 */
	public static int betweenDays(Date sdate, Date edate) {
		Calendar beginDate = getCalendar(sdate);
		Calendar endDate = getCalendar(edate);
		return betweenDays(beginDate, endDate);
	}

	public static Calendar getCalendar(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH) + 1;
		int day = calendar.get(Calendar.DATE);
		calendar.set(year, month, day);
		return calendar;
	}

	/**
	 * 计算日期相隔多少天
	 * 
	 * @param beginDate
	 * @param endDate
	 * @return
	 */
	public static int betweenDays(Calendar beginDate, Calendar endDate) {
		if (beginDate.get(Calendar.YEAR) == endDate.get(Calendar.YEAR)) {
			return endDate.get(Calendar.DAY_OF_YEAR)
					- beginDate.get(Calendar.DAY_OF_YEAR);
		} else {
			if (beginDate.getTimeInMillis() < endDate.getTimeInMillis()) {
				int days = beginDate.getActualMaximum(Calendar.DAY_OF_YEAR)
						- beginDate.get(Calendar.DAY_OF_YEAR)
						+ endDate.get(Calendar.DAY_OF_YEAR);
				for (int i = beginDate.get(Calendar.YEAR) + 1; i < endDate
						.get(Calendar.YEAR); i++) {
					Calendar c = Calendar.getInstance();
					c.set(Calendar.YEAR, i);
					days += c.getActualMaximum(Calendar.DAY_OF_YEAR);
				}
				return days;
			} else {
				int days = endDate.getActualMaximum(Calendar.DAY_OF_YEAR)
						- endDate.get(Calendar.DAY_OF_YEAR)
						+ beginDate.get(Calendar.DAY_OF_YEAR);
				for (int i = endDate.get(Calendar.YEAR) + 1; i < beginDate
						.get(Calendar.YEAR); i++) {
					Calendar c = Calendar.getInstance();
					c.set(Calendar.YEAR, i);
					days += c.getActualMaximum(Calendar.DAY_OF_YEAR);
				}
				return days;
			}
		}
	}

	public static DateFormat getDateFormat(String dateFormat) {
		Map<String, DateFormat> map = threadLocal.get();
		DateFormat df = map.get(dateFormat);
		if (df == null) {
			df = new SimpleDateFormat(dateFormat);
			map.put(dateFormat, df);
		}
		return df;
	}

	// 获取当前时间
	public static String getcurrentTime() {
		String current = DateUtil.dateToString(new Date(),
				DateUtil.YYYY_MM_DD_HH_MM_SS);
		return current;
	}

	// 获取上个月的时间
	public static String getlastMonTime() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, 1);
		String current = DateUtil
				.dateToString(new Date(cal.getTime().getTime()),
						DateUtil.YYYY_MM_DD_HH_MM_SS);
		return current;
	}

	public static long getlastMothTime() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, 1);
		return cal.getTime().getTime();
	}

	/**
	 * 获取与给定日期参数相差天的日期
	 * 
	 * @param date
	 * @param differdays
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Date newDate(Date srcDate, int differdays) {
		Date date = new Date(srcDate.getTime());
		if (date == null) {
			return new Date();
		}
		date.setDate(date.getDate() + differdays);
		return date;
	}

	/**
	 * 根据传入的日期，格式化为指定的日期格式
	 * 
	 * @param date
	 *            日期参数
	 * @param dateFormat
	 *            格式 例如:yyyy-MM-dd
	 * @return
	 */
	public static String dateToString(Date date, String dateFormat) {
		try {
			if (date == null) {
				return null;
			}
			return getDateFormat(dateFormat).format(date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 将日期转化为字符串，默认格式为yyyy-MM-dd
	 * 
	 * @param date
	 * @return
	 */
	public static String dateToString(Date date) {
		try {
			if (date == null) {
				return "";
			}
			return getDateFormat(YYYY_MM_DD).format(date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 根据传入的日期，可根据differdays 参数设置到另一日期，再格式化日期
	 * 
	 * @param date
	 *            日期参数
	 * @param differdays
	 *            与给定的日期相差天数 负数表示指定日期前多少天 正数表示日期后多少天
	 * @param dateFormat
	 *            格式 例如:yyyy-MM-dd
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static String dateToString(Date srcDate, int differdays,
			String dateFormat) {
		Date date = new Date(srcDate.getTime());
		date.setDate(date.getDate() + differdays);
		try {
			return getDateFormat(dateFormat).format(date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取指定参数在一年中所处的周期
	 * 
	 * @param date
	 * @param differdays
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static String getWeek(Date srcDate, int differdays) {
		Date date = new Date(srcDate.getTime());
		date.setDate(date.getDate() + differdays);
		return getDateFormat("w").format(date);
	}

	/**
	 * 根据给定日期，按需要转换的格式转换成字符串
	 * 
	 * @param dateString
	 * @param dateFormat
	 * @return
	 */
	public static Date stringToDate(String dateString, String dateFormat) {
		try {
			if (StringUtil.isEmpty(dateString)) {
				return null;
			}
			return getDateFormat(dateFormat).parse(dateString);
		} catch (Exception e) {
			log.error("日期格式转换错误", e);
		}
		return null;
	}

	/**
	 * 获取一月中的最后一天
	 * 
	 * @param date
	 * @param differdays
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Date getLastDayOfMonth(Date srcDate, int differdays) {
		Date date = new Date(srcDate.getTime());
		date.setDate(date.getDate() + differdays);
		Calendar cDay1 = Calendar.getInstance();
		cDay1.setTime(date);
		final int lastDay = cDay1.getActualMaximum(Calendar.DAY_OF_MONTH);
		Date lastDate = cDay1.getTime();
		lastDate.setDate(lastDay);
		return lastDate;
	}

	/**
	 * 获取一月中的第一天
	 * 
	 * @param date
	 * @param differdays
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Date getFirstDayOfMonth(Date srcDate, int differdays) {
		Date date = new Date(srcDate.getTime());
		date.setDate(date.getDate() + differdays);
		Calendar cDay1 = Calendar.getInstance();
		cDay1.setTime(date);
		final int lastDay = cDay1.getActualMinimum(Calendar.DAY_OF_MONTH);
		Date lastDate = cDay1.getTime();
		lastDate.setDate(lastDay);
		return lastDate;
	}

	/**
	 * 获取给定日期所在周的第一天的时间
	 * 
	 * @param date
	 * @param differdays
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Date getFirstDayOfWeek(Date srcDate, int differdays) {
		Date date = new Date(srcDate.getTime());
		date.setDate(date.getDate() + differdays);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		Date firstDateOfWeek; // 得到当天是这周的第几天
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); // 减去dayOfWeek,得到第一天的日期，因为Calendar用０－６代表一周七天，所以要减一
		calendar.add(Calendar.DAY_OF_WEEK, -(dayOfWeek - 1));
		firstDateOfWeek = calendar.getTime(); // 每周7天，加６，得到最后一天的日子
		return firstDateOfWeek;
	}

	/**
	 * 获取一周中的最后一天
	 * 
	 * @param date
	 * @param differdays
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Date getLastDayOfWeek(Date srcDate, int differdays) {
		Date date = new Date(srcDate.getTime());
		date.setDate(date.getDate() + differdays);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		Date lastDateOfWeek; // 得到当天是这周的第几天
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); // 减去dayOfWeek,得到第一天的日期，因为Calendar用０－６代表一周七天，所以要减一
		calendar.add(Calendar.DAY_OF_WEEK, -(dayOfWeek - 1));
		calendar.add(Calendar.DAY_OF_WEEK, 6);
		lastDateOfWeek = calendar.getTime();
		return lastDateOfWeek;
	}

	/**
	 * 获取一年中的第一个月
	 * 
	 * @param date
	 * @param differmonths
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Date getFirstMonthOfYear(Date srcDate, int differmonths) {
		Date date = new Date(srcDate.getTime());
		date.setMonth(date.getMonth() + differmonths);
		Calendar cDay1 = Calendar.getInstance();
		cDay1.setTime(date);
		date.setDate(cDay1.getActualMinimum(Calendar.DAY_OF_MONTH));
		date.setMonth(cDay1.getActualMinimum(Calendar.MONTH));
		return getFirstSecondOfOneDay(date);
	}

	/**
	 * 获取一年中的最后一月
	 * 
	 * @param date
	 * @param differmonths
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Date getLastMonthOfYear(Date srcDate, int differmonths) {
		Date date = new Date(srcDate.getTime());
		date.setMonth(date.getMonth() + differmonths);
		Calendar cDay1 = Calendar.getInstance();
		cDay1.setTime(date);
		date.setDate(cDay1.getActualMaximum(Calendar.DAY_OF_MONTH));
		date.setMonth(cDay1.getActualMaximum(Calendar.MONTH));
		return getLastSecondOfOneDay(date);
	}

	/**
	 * 获取一天中的第一秒时间
	 * 
	 * @param date
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Date getFirstSecondOfOneDay(Date srcDate) {
		Date date = new Date(srcDate.getTime());
		Calendar c = Calendar.getInstance();
		date.setHours(c.getActualMinimum(Calendar.HOUR_OF_DAY));
		date.setMinutes(c.getActualMinimum(Calendar.MINUTE));
		date.setSeconds(c.getActualMinimum(Calendar.SECOND));
		return date;
	}

	/**
	 * 获取一天中最后一秒时间
	 * 
	 * @param date
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Date getLastSecondOfOneDay(Date srcDate) {
		Date date = new Date(srcDate.getTime());
		Calendar c = Calendar.getInstance();
		date.setHours(c.getActualMaximum(Calendar.HOUR_OF_DAY));
		date.setMinutes(c.getActualMaximum(Calendar.MINUTE));
		date.setSeconds(c.getActualMaximum(Calendar.SECOND));
		return date;
	}

	@SuppressWarnings("deprecation")
	public static void main(String[] args) {
		Date date = new Date();
		date = getFirstMonthOfYear(date, 0);
		System.out.println(date.toLocaleString());
	}

}